<template>
    <a-space direction="vertical">
      <a-card title="交易报文模板配置">
        <a-form ref="searchRef" name="searchBar" :model="searchFormState" :labelCol="{ span: 5, offset: 1 }" @finish="handleSearch">
          <a-row :gutter="24">
            <a-col :span="8">
              <a-form-item name="msgTemplateCode" label="报文模板编号">
                <a-input v-model:value="searchFormState.msgTemplateCode"  placeholder="" ></a-input>
              </a-form-item>
            </a-col>
            <a-col :span="8">
              <a-form-item name="msgTemplateName" label="报文模板名称">
                <a-input v-model:value="searchFormState.msgTemplateName" placeholder="" ></a-input>
              </a-form-item>
            </a-col>
          </a-row>
          <a-row>
            <a-col :span="24" style="text-align: right">
              <a-button type="primary" html-type="submit" :loading="searchLoading" >搜索</a-button>
              <a-button style="margin: 0 8px" @click="() => searchRef?.resetFields()" >重置</a-button>
            </a-col>
          </a-row>
        </a-form>
      </a-card>
      <a-card>
        <a-space>
          <a-button @click="showModal" type="primary"><template #icon> <appstore-add-outlined /> </template>新增</a-button>
          <a-button @click="showEditModal" style="background-color: #f6ffed; color: #237804; border-color: #b7eb8f"><template #icon> <form-outlined /> </template>修改</a-button>
          <a-button @click="showDelete" type="primary" danger><template #icon> <delete-outlined /> </template>删除</a-button>
          <!-- 新增详情按钮 -->
          <a-button @click="showDetailModal" style="background-color: #e6f7ff; color: #1890ff; border-color: #91d5ff">
            <template #icon><eye-outlined /></template>详情
          </a-button>          
        </a-space>
      </a-card>
      <a-card title="查询结果">
        <a-table class="ant-table-striped"
          :rowClassName="
            (_record: any, index: number) => (index % 2 === 1 ? 'table-striped' : null)
          "
          :columns="columns"
          :data-source="data"
          rowKey="id"
          :loading="searchLoading"
          :rowSelection="rowSelection"
          @change="
            (pagination: any) => {
              handleSearch(pagination);
            }
          "
          :pagination="{
            position: [`bottomRight`],
            showSizeChanger: true,
            showQuickJumper: true,
            current: pageNum,
            pageSize,
            total: total,
            showTotal: (total: any) => `总计 ${total} 条记录`,
          }">
          <template #bodyCell="{ column, text }">
            <template v-if="column.dataIndex === 'name'">
              <a>{{ text }}</a>
            </template>
          </template>
        </a-table>
      </a-card>
      <a-modal
        ref="modalRef"
        v-model:visible="visible"
        @ok="handleOk"
        style="width: 1200px; top: 0"
      >
        <template #title>
          <div ref="modalTitleRef" style="width: 100%; cursor: move">
            {{ currentAction }}交易报文模板
          </div>
        </template>
        <a-form ref="formRef" :model="formState" :labelCol="{ span: 5, offset: 1 }" name="form_in_modal">
          <a-row :gutter="24">
            <a-col :span="14" :offset="6">
              <a-form-item 
                name="msgTemplateCode" 
                label="报文模板编号"
                :rules="[{ required: true, message: '请输入报文模板编号' }]"
                >
                 <a-input v-model:value="formState.msgTemplateCode" :disabled="currentAction === action.edit"/>
              </a-form-item>
            </a-col>
          </a-row>          
          <a-row :gutter="24">
            <a-col :span="14" :offset="6">
              <a-form-item
                name="msgTemplateName"
                label="报文模板名称"
                :rules="[{ required: true, message: '请输入报文模板名称' }]"
              >
                <a-input v-model:value="formState.msgTemplateName"/>
              </a-form-item>
            </a-col>
          </a-row>
          <a-row :gutter="24">
            <a-col :span="14" :offset="6">
              <a-form-item 
                name="transChannel" 
                label="交易渠道"
                :rules="[{ required: true, message: '请输入交易渠道' }]"
                >
                <a-select
                  v-model:value="formState.transChannel"
                  placeholder="请选择交易渠道"
                  :loading="transChannelLoading"
                  allowClear 
                  @change="handleTransChannelSelectChange " 
                >              
                  <!-- 遍历渠道平台列表生成选项 -->
                  <a-select-option 
                    v-for="transChannel in transChannelList" 
                    :key="transChannel.transChannelCode" 
                    :value="transChannel.transChannelCode"
                  >
                    {{ transChannel.transChannelName }}
                  </a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
          </a-row>
          <a-row :gutter="24">
            <a-col :span="14" :offset="6">
              <a-form-item 
                name="taskType" 
                label="任务类型"
                :rules="[{ required: true, message: '请输入任务类型' }]"
                >
                <a-select
                  v-model:value="formState.taskType"
                  placeholder="请选择任务类型"
                  :loading="taskTypeLoading"
                  allowClear        
                >
                  <!-- 遍历字典列表生成选项 -->
                  <a-select-option 
                    v-for="dictDate in taskTypeList" 
                    :key="dictDate.dictType" 
                    :value="dictDate.dictValue"
                  >
                    {{ dictDate.dictLabel }}
                  </a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
          </a-row>           
          <a-row :gutter="24">
            <a-col :span="14" :offset="6">
              <a-form-item 
                name="msgTemplateContent" 
                label="报文模板内容"
                :rules="[{ required: true, message: '请输入报文模板内容' }]"
                >
                <a-upload
                  name="file"
                  :show-upload-list="false"
                  :before-upload="beforeUpload"
                  :custom-request="handleFileUpload"
                >
                  <a-button>
                    <upload-outlined /> 选择文件
                  </a-button>
                </a-upload>
                <p v-if="formState.fileName" class="file-name">
                  已选择: {{ formState.fileName }}
                </p>
              </a-form-item>
            </a-col>
          </a-row>   
          <a-row :gutter="24">
            <a-col :span="14" :offset="6">
              <a-form-item 
                name="msgTemplateType" 
                label="报文模板类型"
                :rules="[{ required: true, message: '请输入报文模板类型' }]"
                >
                <a-select
                  v-model:value="formState.msgTemplateType"
                  placeholder="请选择报文模板类型"
                  :loading="msgTemplateTypeLoading"
                  allowClear        
                >
                  <!-- 遍历字典列表生成选项 -->
                  <a-select-option 
                    v-for="dictDate in msgTemplateTypeList" 
                    :key="dictDate.dictType" 
                    :value="dictDate.dictValue"
                  >
                    {{ dictDate.dictLabel }}
                  </a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
          </a-row>  
          <a-row :gutter="24">
            <a-col :span="14" :offset="6">
              <a-form-item v-if="currentAction === action.edit" name="msgTemplateVersion" label="报文模板版本号" >
                <a-input v-model:value="formState.msgTemplateVersion" disabled />
              </a-form-item>
            </a-col>
          </a-row>                                   
        </a-form>
      </a-modal>

      <!-- 详情弹窗模板修改 -->
      <a-modal
        v-model:visible="detailVisible"
        title="报文模板详情"
        :maskClosable="false"
        @cancel="handleDetailCancel"
        :footer="null" 
        style="width: 1200px"
      >
        <a-row :gutter="16">
          <!-- 左侧窄列：显示“报文模板内容”标签 -->
          <a-col :span="4">
            <div class="detail-label">报文模板内容</div>
          </a-col>
          <!-- 右侧宽列：显示内容文本框 -->
          <a-col :span="20">
            <a-textarea 
              v-model:value="detailForm.msgTemplateContent" 
              :rows="12" 
              readonly
              allow-clear 
              show-count 
              max-length="2000"
              style="width: 100%; border-radius: 4px; border-color: #d9d9d9;"
            />
          </a-col>
        </a-row>
      </a-modal>      
    </a-space>
  </template>
  <script lang="ts" setup>
  // base library
  import { LISTHEADER } from "./config"; // 从同级config.ts文件中导入表头
  import { listQuery, add, edit, del} from "@/api/pmManagement/pmMsgTemplate/pmMsgTemplate";
  import { fetchDictData, DictItem, convertDictValue, TransChannelItem, fetchTransChannelList, handleTransChannelChange } from "@/utils/utils"; // 导入公共方法和接口
  import { onMounted } from "@vue/runtime-core";
  import {
    computed,
    createVNode,
    reactive,
    ref,
    toRaw,
    unref,
  } from "vue";
  import { FormInstance, message, Modal } from "ant-design-vue";
  import { ExclamationCircleOutlined, DeleteOutlined, UploadOutlined, EyeOutlined  } from "@ant-design/icons-vue";
  
  const searchRef = ref<FormInstance>();
  let searchLoading = ref(true);
  const searchFormState: { [propName: string]: any } = reactive({});
  
  const columns = LISTHEADER;
  let pageNum = ref(1);
  let pageSize = ref(10);
  let total = ref(0);
  let data = ref([]);

  // 渠道平台列表
  const transChannelList = ref<TransChannelItem[]>([]);
  const transChannelLoading = ref(false);

  const taskTypeList = ref<DictItem[]>([]);
  const taskTypeLoading = ref(false);

  const msgTemplateTypeList = ref<DictItem[]>([]);
  const msgTemplateTypeLoading = ref(false);

  // 在脚本中新增变量
  const hasUploadedNewFile = ref(false); // 标记是否上传了新文件  

  const handleSearch = (values?: any) => {
    searchLoading.value = true;
    console.log("Received values of form: ", values);
    console.log("searchFormState: ", searchFormState);
    let parameter = { ...searchFormState };
    if (values?.current) {
      // 分页切换
      pageNum.value = values?.current;
      pageSize.value = values?.pageSize;
    } else {
      // 搜索
      selectedRowKeys.value = [];
      selectedRows.value = [];
      pageNum.value = 1;
    }
    const requestParameters = Object.assign({}, parameter, {
      pageNum: pageNum.value,
      pageSize: pageSize.value,
    });
    console.log("loadData request parameters:", requestParameters);
  
    // 列表查询及条件查询
    listQuery(requestParameters).then(
      (res: {
        code: number | string;
        msg: string;
        total: number;
        rows: any;
      }) => {
        console.log("打印完整的返回信息：" + res);
        searchLoading.value = false;
        const { code, msg, total: count, rows } = res;
        console.log("接口编码：" + code);
        console.log("接口信息：" + JSON.stringify(rows, null, 2))
        if (code === 200) {
          data.value = rows;
          total.value = count;
        } else {
          total.value = 0;
          data.value = [];
          pageNum.value = 1;
          message.error(msg);
        }
      }
    );
  };
  type T = any
  // 查询出的数据表单展示后，选择数据，对选中的数据进行赋值
  const selectedRowKeys = ref<string[]>([]); // 一般存放选中数据的id，由rowKey控制，rowKey取啥字段就存啥字段的值
  const selectedRows = ref<T[]>([]); // 存放选中行的所有数据
  const onSelectChange = (changableRowKeys: string[], changableRows: T[]) => {
    console.log("选中的行ID:", selectedRowKeys);
    console.log("选中的行数据:", selectedRows);
    console.log("selectedRowKeys changed: ", changableRowKeys);
    selectedRowKeys.value = changableRowKeys;
    selectedRows.value = changableRows;
  };
  const rowSelection = computed(() => {
    return {
      selectedRowKeys: unref(selectedRowKeys),
      onChange: onSelectChange,
      hideDefaultSelections: false,
    };
  });
  enum action {
    add = "新增",
    edit = "编辑",
  }
  const currentAction = ref(action.add);
  const visible = ref<boolean>(false);
  const modalTitleRef = ref<HTMLElement>();

  // 表单字段定义，一般是弹窗中的表单
  interface FormValues {
    id: string;
    msgTemplateCode: string;
    msgTemplateName: string;
    transChannel: string;
    channelName: string;
    msgTemplateContent: string;
    fileName: string; // 存储文件名
    taskType: string;
    msgTemplateType: string;
    msgTemplateVersion: string;
  }
  const formRef = ref<FormInstance>();
  const formState = reactive<FormValues>({ // 表单数据初始化
    id: "",
    msgTemplateCode: "",
    msgTemplateName: "",
    transChannel: "",
    channelName: "",
    msgTemplateContent: "",
    fileName: "", // 新增文件名存储
    taskType: "",
    msgTemplateType: "",
    msgTemplateVersion: "1" // 默认值为 1
  });
  // 备份初始化为空的表单数据，用于新增按钮时置空可能存在的遗留表单数据
  const formBackup = { ...formState };
  const reset = () => {
    formRef.value?.resetFields(); 
    Object.assign(formState, formBackup);
  }

  // 文件上传前校验
  const beforeUpload = (file: File) => {
    const fileName = file.name.toLowerCase();
    // 仅允许三种格式，通过后缀精准判断
    const isAllowedFormat = fileName.endsWith('.json') || fileName.endsWith('.xml') || fileName.endsWith('.imix');
    const isLt2M = file.size / 1024 / 1024 < 2;

    if (!isAllowedFormat) {
      message.error('仅支持上传 JSON、XML、IMIX 格式的文件!');
      return false;
    }
    if (!isLt2M) {
      message.error('文件大小不能超过2MB!');
      return false;
    }
    
    // 自动识别文件类型，赋值给 msgTemplateType（与下拉框选项值对应）
    if (fileName.endsWith('.json')) {
      formState.msgTemplateType = "0";
    } else if (fileName.endsWith('.xml')) {
      formState.msgTemplateType = "1";
    } else if (fileName.endsWith('.imix')) {
      formState.msgTemplateType = "2";
    }
    
    return true;
  };

  // 处理文件上传（读取文件内容）
  const handleFileUpload = (options: any) => {
    const { file } = options;
    const reader = new FileReader();

    // 文件读取成功回调
    reader.onload = (e) => {
      // 三种格式均按文本读取，直接存入表单
      formState.msgTemplateContent = e.target?.result as string;
      formState.fileName = file.name;
      hasUploadedNewFile.value = true; // 标记上传了新文件（用于编辑时版本控制）
      options.onSuccess(); // 通知上传组件上传成功
    };

    // 文件读取失败回调
    reader.onerror = () => {
      message.error('文件读取失败，请重试');
      options.onError(); // 通知上传组件上传失败
    };

    // 统一使用 readAsText 读取（适配 JSON/XML/IMIX 文本格式）
    reader.readAsText(file);
  };  
  
  // 新增弹窗页面，并对表单数据进行初始化为空，防止出现先打开编辑弹窗后，遗留表单数据
  const showModal = () => {
    reset();
    formState.id = "";//resetFields() 对 id 字段无效！因为弹窗表单中没有 id 对应的表单控件,手动重置id，双重保障         
    visible.value = true;
    currentAction.value = action.add;
  };
  // 弹窗中渠道平台选择器的change事件直接调用工具方法
  const handleTransChannelSelectChange = (code: string) => {
    // 传入参数：选中的编码、币种列表、表单对象
    handleTransChannelChange(code, transChannelList.value, formState);
  };  
  // 编辑弹窗页面
  const showEditModal = () => {
    if (selectedRowKeys.value.length > 1)
      message.error("仅能选择一条记录进行操作");
    if (selectedRowKeys.value.length === 0)
      message.error("请选择一条记录进行操作");
    if (selectedRowKeys.value.length === 1) {
      currentAction.value = action.edit;
      visible.value = true;
      formRef.value?.resetFields();
      // 渲染【编辑】弹窗中的数据
      // 1. 获取选中行数据
      const rowData = selectedRows.value[0];

      // 重置文件上传标记（关键）
      hasUploadedNewFile.value = false;       

      // 2. 批量转换枚举字段（根据字典类型和字典列表）
      const convertedData = {
        ...rowData,
        // 转换：要素类型（字典类型 'task_type'）
        taskType: convertDictValue(
          'task_type',
          rowData.taskType,
          taskTypeList.value
        ),        
        // 转换：要素类型（字典类型 'msg_template_type'）
        msgTemplateType: convertDictValue(
          'msg_template_type',
          rowData.msgTemplateType,
          msgTemplateTypeList.value
        ),                      
      }; 
      // 3. 赋值数据前，强制清除文件相关字段（关键步骤）
      formState.fileName = ""; // 清除文件名
      formState.msgTemplateContent = ""; // 清除文件内容（编辑时应从选中行获取内容，而非新增残留）    
      Object.assign(formState, convertedData);
    }
  };
  // 弹窗页面中确定按钮点击事件，由于新增和修改共用一个弹窗页面，故可以在此方法中判断新增和更新方法
  const handleOk = (e: MouseEvent) => {
    console.log(e);
    // visible.value = false;
    formRef.value
      .validateFields()
      .then((values) => {
        console.log("Received values of form: ", values);
        console.log("formState: ", toRaw(formState));
        visible.value = false;
        // 当前action为add时，调用新增方法add
        if (currentAction.value === action.add) {
          add(formState).then((res: { code: number; msg: string; }) => {
            const { code, msg } = res;
            if (code === 200) {
              Modal.success({
                title: msg,
              });
              formRef.value?.resetFields();
              console.log("reset formState: ", toRaw(formState));
            } else {
              Modal.error({
                title: msg,
              });
            }
            handleSearch();
          });
        }
        // 当前action为edit时，调用编辑方法edit
        if (currentAction.value === action.edit) {
          // 核心：判断是否上传了新文件，而非内容是否变化
          if (hasUploadedNewFile.value) {
             // 内容修改：版本号+1（模拟插入新记录逻辑）
            const currentVersion = parseInt(formState.msgTemplateVersion || "1");
            formState.msgTemplateVersion = (currentVersion + 1).toString();
            formState.id = "";
            add(formState).then((res: { code: number; msg: string; }) => {
              const { code, msg } = res;
              if (code === 200) {
                Modal.success({
                  title: msg,
                });
                formRef.value?.resetFields();
                console.log("reset formState: ", toRaw(formState));
              } else {
                Modal.error({
                  title: msg,
                });
              }
              handleSearch();
            });           
          } else {
            edit(formState).then((res: { code: number; msg: string; }) => {
              const { code, msg } = res;
              if (code === 200) {
                Modal.success({
                  title: msg,
                });
                formRef.value?.resetFields();
                console.log("reset formState: ", toRaw(formState));
              } else {
                Modal.error({
                  title: msg,
                });
              }
              handleSearch();
            }); 
          }
        }
      })
      .catch((info) => {
        console.log("Validate Failed:", info);
      });
  };
  // 删除弹窗页面，选中数据后，点击删除，调用del删除方法
  const showDelete = () => {
    if (selectedRowKeys.value.length === 0){
      message.error("请选择一条记录进行操作");
    } 
    
    // 核心：提取选中行的 msgTemplateCode + 去重（避免重复删除同一模板）
    const uniqueTemplateCodes = Array.from(
      new Set(selectedRows.value.map(row => row.msgTemplateCode))
    );
    Modal.confirm({
      title: "请确认是否操作删除?",
      icon: createVNode(ExclamationCircleOutlined),
      okText: "删除",
      okType: "danger",
      cancelText: "取消",
      onOk() {
        console.log("selectedRows: ", toRaw(selectedRows.value[0]).id,selectedRows);
        console.log("uniqueTemplateCodes: ", uniqueTemplateCodes);
        del(uniqueTemplateCodes).then((res: { code: number; msg: string; }) => {
          const { code, msg } = res;
          if (code === 200) {
            console.log("resp: ", toRaw(res));
            Modal.success({
              title: msg,
            });
            handleSearch();
          } else {
            Modal.error({
              title: msg,
            });
          }
        });
      },
      onCancel() {
        console.log("Cancel");
      },
    });
    
  };

  // 详情弹窗状态
  const detailVisible = ref<boolean>(false);
  // 详情表单数据
  const detailForm = reactive<FormValues>({
    id: "",
    msgTemplateCode: "",
    msgTemplateName: "",
    transChannel: "",
    channelName: "",
    msgTemplateContent: "",
    fileName: "",
    taskType: "",
    msgTemplateType: "",
    msgTemplateVersion: ""
  });

  // 打开详情弹窗
  const showDetailModal = () => {
    // 校验选中状态
    if (selectedRowKeys.value.length > 1) {
      message.error("仅能选择一条记录查看详情");
      return;
    }
    if (selectedRowKeys.value.length === 0) {
      message.error("请选择一条记录查看详情");
      return;
    }
    // 赋值详情数据
    Object.assign(detailForm, selectedRows.value[0]);
    detailVisible.value = true;
  };

  // 关闭详情弹窗
  const handleDetailCancel = () => {
    detailVisible.value = false;
  };
  
  onMounted(() => {
    searchLoading.value = false;
    fetchTransChannelList(transChannelList, transChannelLoading);
    fetchDictData("task_type", taskTypeList, taskTypeLoading);
    fetchDictData("msg_template_type", msgTemplateTypeList, msgTemplateTypeLoading);
    //   handleSearch();
  });
  </script>
  <script lang="ts">
  import {
    AppstoreAddOutlined,
    FormOutlined,
  } from "@ant-design/icons-vue";
  
  export default {
    name: "pmMsgTemplate",
    components: {
      AppstoreAddOutlined,
      FormOutlined,
    },
  };
  </script>
  
  <style type="less" scoped>
  /* .ant-form-item-label > label {
    width:150px!important;
    justify-content: end!important;
  } */
  .ant-table-striped :deep(.table-striped) td {
    background-color: #fafafa;
  }
  
  /* 新增文件名称显示样式 */
  .file-name {
    margin-top: 8px;
    color: #1890ff;
    font-size: 12px;
  }

  /* 调整上传按钮样式 */
  :deep(.ant-upload) {
    margin-bottom: 8px;
  }   

  /* 详情弹窗左侧标签样式 */
  .detail-label {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    background-color: #f5f5f5;
    border: 1px solid #d9d9d9;
    border-right: none;
    border-radius: 4px 0 0 4px;
    font-weight: 600;
  }

  /* 文本框边框调整（配合左侧标签） */
  :deep(.ant-textarea) {
    border-radius: 0 4px 4px 0 !important;
  }  
  </style>
  